package com.ecarx.vhaltests.hy11.testcases.user;

import android.car.Car;
import android.car.user.CarUserManager;
import android.car.user.UserCreationResult;
import android.car.user.UserRemovalResult;
import android.car.user.UserSwitchResult;
import android.content.res.Resources;
import android.content.pm.UserInfo;
import android.os.UserManager;
import android.os.SystemProperties;

import com.android.internal.infra.AndroidFuture;

import com.ecarx.vhaltests.VhalUnitTestBase;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import java.io.File;

@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class MultiuserAndProfileTest extends VhalUnitTestBase {
    private static Car mCar;
    private static CarUserManager carUserManager;
    private static final int SYSTEM_USER_ID = 0;
    private static final int FIRST_USER_ID = 10;
    private static final int MAXIMUM_USERS = 9;
    private static final int OWNER_PROFILE_ID = 1;
    private static final int EPHEMERAL_PROFILE_ID = 12;
    private static final int GUEST_PROFILE_ID = 13;
    private static final int FAMILY_PRIFILE_ID_MIN = 2;
    private static final int INVALID_USER_ID = -1;
    private static final long MANAGE_USER_INTERVAL_TIME = 3000;
    private static final String OWNER_USER_ID_PROPERTY = "persisr.vhaltest.owner_user_id";
    private static final String FAMILY_USER_ID_PROPERTY = "persisr.vhaltest.family_user_id";
    private static final String EPHEMERAL_USER_ID_PROPERTY = "persisr.vhaltest.ephemeral_user_id";
    private static final String GUEST_USER_ID_PROPERTY = "persisr.vhaltest.guest_user_id";
    private static final String VHAL_PROFILE_FILE_PATH = "/data/vendor/vehicle_hal/profile_";

    @BeforeClass
    public static void testInit() {
        mCar = Car.createCar(mContext);
        carUserManager = (CarUserManager) mCar.getCarManager(Car.CAR_USER_SERVICE);
    }

    @Test
    // 测试与多用户Profile相关的一些基础配置以及系统初始化场景
    public void test_MultiuserAndProfile_001() {
        try {
            // 系统处于启用系统无头用户模式
            Assert.assertTrue(UserManager.isHeadlessSystemUserMode());
            // 系统处于支持多用户模式
            Assert.assertTrue(UserManager.supportsMultipleUsers());
            // 系统内的Guest游客不具备FLAG_EPHEMERAL
            Assert.assertFalse(
                Resources.getSystem().getBoolean(com.android.internal.R.bool.config_guestUserEphemeral));
            // 系统内的最大用户数量为9: 1个system user + 8个human user
            Assert.assertEquals(
                Resources.getSystem().getInteger(com.android.internal.R.integer.config_multiuserMaximumUsers), MAXIMUM_USERS);
            // 系统初始化时默认会存在userID-0和userID-10两个用户,
            // userID-0是系统无头用户，不是有效用户; userID-10是非系统用户，属于有效用户
            Assert.assertFalse(carUserManager.isValidUser(SYSTEM_USER_ID));
            Assert.assertTrue(carUserManager.isValidUser(FIRST_USER_ID));
            SystemProperties.set(GUEST_USER_ID_PROPERTY, String.valueOf(FIRST_USER_ID));
            // 游客profile文件存在
            File file = new File(VHAL_PROFILE_FILE_PATH + GUEST_PROFILE_ID);
            Assert.assertTrue(file.exists());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试创建车主用户, 创建成功
    public void test_MultiuserAndProfile_002() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result = carUserManager.createUser(
                "Owner", "android.os.usertype.full.SECONDARY", UserInfo.FLAG_ADMIN);
            // 创建成功
            Assert.assertTrue(result.get().isSuccess());
            UserInfo userInfo = result.get().getUser();
            // human user的userID从10开始分配, 因此创建的用户的userID一定大于10
            Assert.assertTrue(userInfo.id > FIRST_USER_ID);
            SystemProperties.set(OWNER_USER_ID_PROPERTY, String.valueOf(userInfo.id));
            // 车主用户的UserFlags为0x402
            Assert.assertEquals(UserInfo.FLAG_FULL, (userInfo.flags & UserInfo.FLAG_FULL));
            Assert.assertEquals(UserInfo.FLAG_ADMIN, (userInfo.flags & UserInfo.FLAG_ADMIN));
            // 车主profile文件存在
            File file = new File(VHAL_PROFILE_FILE_PATH + OWNER_PROFILE_ID);
            Assert.assertTrue(file.exists());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试创建第2个车主用户, 创建失败
    public void test_MultiuserAndProfile_003() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result = carUserManager.createUser(
                "OWNER", "android.os.usertype.full.SECONDARY", UserInfo.FLAG_ADMIN);
            // 创建失败
            Assert.assertFalse(result.get().isSuccess());
            // VHAL限制车主用户数量不能超过1, 返回结果为STATUS_HAL_FAILURE
            Assert.assertEquals(result.get().getStatus(), UserCreationResult.STATUS_HAL_FAILURE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试创建亲情用户(空白Profile)，创建成功
    public void test_MultiuserAndProfile_004() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result = carUserManager.createUser(
                "FAMILY1", "android.os.usertype.full.SECONDARY", 0);
            // 创建成功
            Assert.assertTrue(result.get().isSuccess());
            UserInfo userInfo = result.get().getUser();
            SystemProperties.set(FAMILY_USER_ID_PROPERTY, String.valueOf(userInfo.id));
            // human user的userID从10开始分配, 因此创建的用户的userID一定大于10
            Assert.assertTrue(userInfo.id > FIRST_USER_ID);
            // 亲情用户的UserFlags为0x400
            Assert.assertEquals(UserInfo.FLAG_FULL, (userInfo.flags & UserInfo.FLAG_FULL));
            // 亲情profile文件存在
            File file = new File(VHAL_PROFILE_FILE_PATH + FAMILY_PRIFILE_ID_MIN);
            Assert.assertTrue(file.exists());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试创建亲情用户(沿用Profile)，创建成功
    public void test_MultiuserAndProfile_005() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result = carUserManager.createUser(
                "FAMILY2", "android.os.usertype.full.SECONDARY", FIRST_USER_ID << 16);
            // 创建成功
            Assert.assertTrue(result.get().isSuccess());
            UserInfo userInfo = result.get().getUser();
            // human user的userID从10开始分配, 因此创建的用户的userID一定大于10
            Assert.assertTrue(userInfo.id > FIRST_USER_ID);
            // 亲情用户的UserFlags为0x400
            Assert.assertEquals(UserInfo.FLAG_FULL, (userInfo.flags & UserInfo.FLAG_FULL));
            // 亲情profile文件存在
            File file = new File(VHAL_PROFILE_FILE_PATH + (FAMILY_PRIFILE_ID_MIN + 1));
            Assert.assertTrue(file.exists());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试多次创建亲情用户, 创建成功
    public void test_MultiuserAndProfile_006() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result1 = carUserManager.createUser(
                "FAMILY3", "android.os.usertype.full.SECONDARY", 0);
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result2 = carUserManager.createUser(
                "FAMILY4", "android.os.usertype.full.SECONDARY", 0);
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result3 = carUserManager.createUser(
                "FAMILY5", "android.os.usertype.full.SECONDARY", 0);
            // 创建成功
            Assert.assertTrue(result1.get().isSuccess());
            Assert.assertTrue(result2.get().isSuccess());
            Assert.assertTrue(result3.get().isSuccess());
            UserInfo userInfo1 = result1.get().getUser();
            UserInfo userInfo2 = result2.get().getUser();
            UserInfo userInfo3 = result3.get().getUser();
            // human user的userID从10开始分配, 因此创建的用户的userID一定大于10
            Assert.assertTrue(userInfo1.id > FIRST_USER_ID);
            Assert.assertTrue(userInfo2.id > FIRST_USER_ID);
            Assert.assertTrue(userInfo3.id > FIRST_USER_ID);
            // 亲情用户的UserFlags为0x400
            Assert.assertEquals(UserInfo.FLAG_FULL, (userInfo1.flags & UserInfo.FLAG_FULL));
            Assert.assertEquals(UserInfo.FLAG_FULL, (userInfo2.flags & UserInfo.FLAG_FULL));
            Assert.assertEquals(UserInfo.FLAG_FULL, (userInfo3.flags & UserInfo.FLAG_FULL));
            // 亲情profile文件存在
            File file1 = new File(VHAL_PROFILE_FILE_PATH + (FAMILY_PRIFILE_ID_MIN + 2));
            File file2 = new File(VHAL_PROFILE_FILE_PATH + (FAMILY_PRIFILE_ID_MIN + 3));
            File file3 = new File(VHAL_PROFILE_FILE_PATH + (FAMILY_PRIFILE_ID_MIN + 4));
            Assert.assertTrue(file1.exists());
            Assert.assertTrue(file2.exists());
            Assert.assertTrue(file3.exists());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试创建第6个亲情用户, 创建失败
    public void test_MultiuserAndProfile_007() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result = carUserManager.createUser(
                "FAMILY6", "android.os.usertype.full.SECONDARY", 0);
            // 创建失败
            Assert.assertFalse(result.get().isSuccess());
            // VHAL限制亲情用户数量不能超过5, 返回结果为STATUS_HAL_FAILURE
            Assert.assertEquals(result.get().getStatus(), UserCreationResult.STATUS_HAL_FAILURE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试创建临时用户, 创建成功
    public void test_MultiuserAndProfile_008() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result = carUserManager.createUser(
                "EPHEMERAL", "android.os.usertype.full.SECONDARY", UserInfo.FLAG_EPHEMERAL);
            // 创建成功
            Assert.assertTrue(result.get().isSuccess());
            UserInfo userInfo = result.get().getUser();
            SystemProperties.set(EPHEMERAL_USER_ID_PROPERTY, String.valueOf(userInfo.id));
            // human user的userID从10开始分配, 因此创建的用户的userID一定大于10
            Assert.assertTrue(userInfo.id > FIRST_USER_ID);
            // 临时用户的UserFlags为0x500
            Assert.assertEquals(UserInfo.FLAG_FULL, (userInfo.flags & UserInfo.FLAG_FULL));
            Assert.assertEquals(UserInfo.FLAG_EPHEMERAL, (userInfo.flags & UserInfo.FLAG_EPHEMERAL));
            // 临时profile文件存在
            File file = new File(VHAL_PROFILE_FILE_PATH + EPHEMERAL_PROFILE_ID);
            Assert.assertTrue(file.exists());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试创建第2个临时用户, 创建失败
    public void test_MultiuserAndProfile_009() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result = carUserManager.createUser(
                "EPHEMERAL", "android.os.usertype.full.SECONDARY", UserInfo.FLAG_EPHEMERAL);
            // 创建失败
            Assert.assertFalse(result.get().isSuccess());
            // VHAL限制临时用户数量不能超过1, 返回结果为STATUS_HAL_FAILURE
            Assert.assertEquals(result.get().getStatus(), UserCreationResult.STATUS_HAL_FAILURE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试创建第2个游客用户(系统初始化默认已有1个游客用户), 创建失败
    public void test_MultiuserAndProfile_010() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            AndroidFuture<UserCreationResult> result = carUserManager.createUser(
                "Owner", "android.os.usertype.full.GUEST", 0);
            // 创建失败
            Assert.assertFalse(result.get().isSuccess());
            // FWK限制用户总数量, 返回结果为STATUS_ANDROID_FAILURE
            Assert.assertEquals(result.get().getStatus(), UserCreationResult.STATUS_ANDROID_FAILURE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试删除所有亲情用户, 删除成功
    public void test_MultiuserAndProfile_011() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            int familyUserId = SystemProperties.getInt(FAMILY_USER_ID_PROPERTY, INVALID_USER_ID);
            if (familyUserId != INVALID_USER_ID) {
                UserRemovalResult result1 = carUserManager.removeUser(familyUserId);
                UserRemovalResult result2 = carUserManager.removeUser(familyUserId + 1);
                UserRemovalResult result3 = carUserManager.removeUser(familyUserId + 2);
                UserRemovalResult result4 = carUserManager.removeUser(familyUserId + 3);
                UserRemovalResult result5 = carUserManager.removeUser(familyUserId + 4);
                // 删除成功
                Assert.assertTrue(result1.isSuccess());
                Assert.assertTrue(result2.isSuccess());
                Assert.assertTrue(result3.isSuccess());
                Assert.assertTrue(result4.isSuccess());
                Assert.assertTrue(result5.isSuccess());
                // 亲情profile文件全部不存在
                File file1 = new File(VHAL_PROFILE_FILE_PATH + FAMILY_PRIFILE_ID_MIN);
                File file2 = new File(VHAL_PROFILE_FILE_PATH + (FAMILY_PRIFILE_ID_MIN + 1));
                File file3 = new File(VHAL_PROFILE_FILE_PATH + (FAMILY_PRIFILE_ID_MIN + 2));
                File file4 = new File(VHAL_PROFILE_FILE_PATH + (FAMILY_PRIFILE_ID_MIN + 3));
                File file5 = new File(VHAL_PROFILE_FILE_PATH + (FAMILY_PRIFILE_ID_MIN + 4));
                Assert.assertFalse(file1.exists());
                Assert.assertFalse(file2.exists());
                Assert.assertFalse(file3.exists());
                Assert.assertFalse(file4.exists());
                Assert.assertFalse(file5.exists());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试删除临时用户, 删除成功
    public void test_MultiuserAndProfile_012() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            int ephemeralUserId = SystemProperties.getInt(EPHEMERAL_USER_ID_PROPERTY, INVALID_USER_ID);
            if (ephemeralUserId != INVALID_USER_ID) {
                UserRemovalResult result = carUserManager.removeUser(ephemeralUserId);
                // 删除成功
                Assert.assertTrue(result.isSuccess());
                // 临时profile文件存在
                File file = new File(VHAL_PROFILE_FILE_PATH + EPHEMERAL_PROFILE_ID);
                Assert.assertTrue(file.exists());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试删除游客用户, 删除失败, 游客用户为当前用户
    public void test_MultiuserAndProfile_013() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            int guestUserId = SystemProperties.getInt(GUEST_USER_ID_PROPERTY, INVALID_USER_ID);
            if (guestUserId != INVALID_USER_ID) {
                UserRemovalResult result = carUserManager.removeUser(guestUserId);
                // 删除失败, 游客用户为当前用户
                Assert.assertFalse(result.isSuccess());
                Assert.assertEquals(result.getStatus(), UserRemovalResult.STATUS_TARGET_USER_IS_CURRENT_USER);
                // 游客profile文件存在
                File file = new File(VHAL_PROFILE_FILE_PATH + GUEST_PROFILE_ID);
                Assert.assertTrue(file.exists());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Test
    // 测试删除车主用户, 删除成功
    public void test_MultiuserAndProfile_014() {
        try {
            Thread.sleep(MANAGE_USER_INTERVAL_TIME);
            int ownerUserId = SystemProperties.getInt(OWNER_USER_ID_PROPERTY, INVALID_USER_ID);
            if (ownerUserId != INVALID_USER_ID) {
                UserRemovalResult result = carUserManager.removeUser(ownerUserId);
                // 删除成功
                Assert.assertTrue(result.isSuccess());
                // 车主profile文件不存在
                File file = new File(VHAL_PROFILE_FILE_PATH + OWNER_PROFILE_ID);
                Assert.assertFalse(file.exists());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

   @Test
   // 测试切换到亲情用户, 切换成功
   // 测试APK的安装与用户相关，切换用户功能需要单独执行测试用例
   public void test_MultiuserAndProfile_015() {
       try {
           Thread.sleep(MANAGE_USER_INTERVAL_TIME);
           int familyUserId = SystemProperties.getInt(FAMILY_USER_ID_PROPERTY, INVALID_USER_ID);
           if (familyUserId != INVALID_USER_ID) {
               AndroidFuture<UserSwitchResult> result = carUserManager.switchUser(familyUserId);
               // 切换成功
               Assert.assertTrue(result.get().isSuccess());
               // 亲情profile文件存在
               File file = new File(VHAL_PROFILE_FILE_PATH + FAMILY_PRIFILE_ID_MIN);
               Assert.assertTrue(file.exists());
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

   @Test
   // 测试切换到临时用户, 切换成功
   // 测试APK的安装与用户相关，切换用户功能需要单独执行测试用例
   public void test_MultiuserAndProfile_016() {
       try {
           Thread.sleep(MANAGE_USER_INTERVAL_TIME);
           int ephemeralUserId = SystemProperties.getInt(EPHEMERAL_USER_ID_PROPERTY, INVALID_USER_ID);
           if (ephemeralUserId != INVALID_USER_ID) {
               AndroidFuture<UserSwitchResult> result = carUserManager.switchUser(ephemeralUserId);
               // 切换成功
               Assert.assertTrue(result.get().isSuccess());
               // 临时profile文件存在
               File file = new File(VHAL_PROFILE_FILE_PATH + EPHEMERAL_PROFILE_ID);
               Assert.assertTrue(file.exists());
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

   @Test
   // 测试切换到游客用户, 切换成功
   // 测试APK的安装与用户相关，切换用户功能需要单独执行测试用例
   public void test_MultiuserAndProfile_017() {
       try {
           Thread.sleep(MANAGE_USER_INTERVAL_TIME);
           int guestUserId = SystemProperties.getInt(GUEST_USER_ID_PROPERTY, INVALID_USER_ID);
           if (guestUserId != INVALID_USER_ID) {
               AndroidFuture<UserSwitchResult> result = carUserManager.switchUser(guestUserId);
               // 切换成功
               Assert.assertTrue(result.get().isSuccess());
               // 游客profile文件存在
               File file = new File(VHAL_PROFILE_FILE_PATH + GUEST_PROFILE_ID);
               Assert.assertTrue(file.exists());
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }

   @Test
   // 测试切换到车主用户, 切换成功
   // 测试APK的安装与用户相关，切换用户功能需要单独执行测试用例
   public void test_MultiuserAndProfile_018() {
       try {
           Thread.sleep(MANAGE_USER_INTERVAL_TIME);
           int ownerUserId = SystemProperties.getInt(OWNER_USER_ID_PROPERTY, INVALID_USER_ID);
           if (ownerUserId != INVALID_USER_ID) {
               AndroidFuture<UserSwitchResult> result = carUserManager.switchUser(ownerUserId);
               // 切换成功
               Assert.assertTrue(result.get().isSuccess());
               // 车主profile文件存在
               File file = new File(VHAL_PROFILE_FILE_PATH + OWNER_PROFILE_ID);
               Assert.assertTrue(file.exists());
           }
       } catch (Exception e) {
           e.printStackTrace();
       }
   }
}
